<?php
/**
 * 分类结点管理 - 管理后台
 *
 * @author birdy <freebirdy@foxmail.com>
 * @link http://www.aiyuangong.com
 */

namespace app\admin\controller\system;

use app\admin\Controller;
use think\Db;
use think\Loader;
use think\Exception;

class Item extends Controller
{
    //结点标识
    protected $tag = '';
    
    //根结点
    protected $rootItem = [];

    //结点字段配置
    protected $fields = [];
    
    //固有字段名称
    protected $title = ['id'=>'ID', 'name' => '名称', 'tag' => '标识', 'remark' => '备注', 'sort'=>'排序'];
    
    //列表字段
    protected $row  = ['id', 'name', 'tag', 'remark', 'fields'=>['text']];

    //模板路径
    protected $form_tpl = '';
    
    //字段存储类型
    protected $field_type = '';
    
    //字段前缀
    protected $field_name = '';
    
    //层级
    protected $level = 2;
    
    //列表显示的按钮
    //例：[['name'=>'编辑', 'url'=>'edit', 'type'=>'layer_open', 'icon' => '&#xe6df;']]
    protected $extend_list_btns = [];

    // 初始化
    public function __construct()
    {
        parent::__construct();
        if (!$this->tag) {
            $this->tag = $this->request->param('tag');
        }
        
        $map = ['pid'=>0, 'tag' => $this->tag, 'status' => 1, 'isdelete'=>0];
        $this->rootItem = Db::name("type")->where($map)->field("id,fields")->find();
        
        if (!$this->rootItem) {
            throw new Exception("结点未初始化");
        }
        
        if (!$this->fields) {
            $this->fields = $this->rootItem['fields'] ? json_decode($this->rootItem['fields'], true) : [];
        }
    }


    /**
     * 分类结点列表
     */
    public function index($tpl = 'system/item/index')
    {
        $model = Loader::model("type");

        // 列表过滤器，生成查询Map对象
        $map = ['pid' => $this->rootItem['id']];
        if ($this::$isdelete !== false) {
            $map['isdelete'] = $this::$isdelete;
        }

        if ($this->request->action() == "recyclebin") {
            $list = $this->datalist($model, $map, "*", '', false, true, false);
            foreach ($list as $k=>$v) {
                $list[$k]['fields'] = json_decode($v['fields'], true);
            }
        } else {
            $list = \Fields::get_tree_data($this->tag, false, '*', false);
            $list = isset($list['_child']) ? $list['_child'] : [];
            foreach ($list as $k=>$v) {
                $list[$k]['fields'] = json_decode($v['fields'], true);
                if ($this->level > 1 && isset($v['_child'])) {
                    foreach ($v['_child'] as $k1=>$v1) {
                        $list[$k]['_child'][$k1]['fields'] = json_decode($v1['fields'], true);
                    }
                }
            }
        }
        
        $this->view->assign('list', $list);
        $this->view->assign("count", count($list));

        $this->view->assign("title", $this->title);
        $this->view->assign("row", $this->row);
        $this->view->assign("pid", $this->rootItem['id']);
        $this->view->assign("fields", reset_by_key($this->fields, 'name'));
        $this->view->assign('extend_list_btns', $this->extend_list_btns);
        return $this->view->fetch($tpl);
    }
    
    /**
     * 回收站
     * @return mixed
     */
    public function recycleBin()
    {
        $this::$isdelete = 1;

        return $this->index('system/item/recycleBin');
    }
    
    /**
     * 添加
     * @return mixed
     */
    public function add()
    {
        if ($this->request->isPost()) {
            // 插入
            $data = $this->request->only('pid,name,tag,remark,sort,status', 'post');
            unset($data['id']);
            if ($this->level < 2 || !isset($data['pid'])) {
                $data['pid'] = $this->rootItem['id'];
            }

            $fields = \Fields::get_data($this->fields, 'post', $this->field_name, $this->field_type);
            if (!is_array($fields)) {
                throw new Exception((string)$fields ? : "未知错误");
            } else {
                $data['fields'] = json_encode($fields);
            }

            $module = $this->request->module();
            // 写入数据
            Db::startTrans();
            try {
                if (class_exists(Loader::parseClass($module, 'model', 'type'))) {
                    //使用模型写入，可以在模型中定义更高级的操作
                    $model = Loader::model('type');
                    $ret = $model->save($data);
                } else {
                    // 简单的直接使用db写入
                    $model = Db::name($this->parseTable('type'));
                    $ret = $model->insert($data);
                }
                // 提交事务
                Db::commit();

                \Fields::clearCache();
                return ajax_return_adv('添加成功');
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();

                return ajax_return_adv_error($e->getMessage());
            }
        } else {
            // 添加
            if ($this->level > 1) {
                $parent = Db::name("type")->where(['pid' => $this->rootItem['id'], 'isdelete'=>0])->column("name", "id");
                $this->view->assign("parent", $parent);
            }
            $this->view->assign("pid", $this->rootItem['id']);
            $this->view->assign("config", ['tpl'=>$this->form_tpl, 'type'=>$this->field_type, 'name'=>$this->field_name]);
            $this->view->assign("title", $this->title);
            $this->view->assign("level", $this->level);
            $this->view->assign("fields", $this->fields);
            $this->view->assign("vo", ['pid'=>0]);
            return $this->view->fetch('system/item/edit');
        }
    }
    
    /**
     * 编辑
     * @return mixed
     */
    public function edit()
    {
        $controller = 'type';
        $module = $this->request->module();

        if ($this->request->isAjax()) {
            // 更新
            $data = $this->request->only('id,pid,name,tag,remark,sort,status', 'post');
            if (!$data['id']) {
                return ajax_return_adv_error("缺少参数ID");
            } else if ($this->level < 2 || !isset($data['pid'])) {
                $data['pid'] = $this->rootItem['id'];
            }

            $fields = \Fields::get_data($this->fields, 'post', $this->field_name, $this->field_type);
            if (!is_array($fields)) {
                throw new Exception((string)$fields ? : "未知错误");
            } else {
                $data['fields'] = json_encode($fields);
            }

            // 更新数据
            Db::startTrans();
            try {
                if (class_exists(Loader::parseClass($module, 'model', $controller))) {
                    // 使用模型更新，可以在模型中定义更高级的操作
                    $model = Loader::model($controller);
                    $ret = $model->isUpdate(true)->save($data, ['id' => $data['id']]);
                } else {
                    // 简单的直接使用db更新
                    $model = Db::name($this->parseTable($controller));
                    $ret = $model->where('id', $data['id'])->update($data);
                }
                // 提交事务
                Db::commit();

                \Fields::clearCache();
                return ajax_return_adv("编辑成功");
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();

                return ajax_return_adv_error($e->getMessage());
            } 
        } else {
            // 编辑
            $id = $this->request->param('id');
            if (!$id) {
                throw new Exception("缺少参数ID");
            }
            $vo = $this->getModel('type')->find($id);
            if (!$vo) {
                throw new HttpException(404, '该记录不存在');
            }
            
            if ($this->level > 1) {
                $parent = Db::name("type")->where(['pid' => $this->rootItem['id'], 'isdelete'=>0])->column("name", "id");
                $this->view->assign("parent", $parent);
            }
            $values = json_decode($vo['fields'], true);
            $this->view->assign("values", $values);
            
            $this->view->assign("vo", $vo);
            $this->view->assign("pid", $this->rootItem['id']);
            $this->view->assign("config", ['tpl'=>$this->form_tpl, 'type'=>$this->field_type, 'name'=>$this->field_name]);
            $this->view->assign("title", $this->title);
            $this->view->assign("level", $this->level);
            $this->view->assign("fields", $this->fields);
            return $this->view->fetch('system/item/edit');
        }
    }
    
    /**
     * 默认删除操作
     */
    public function delete()
    {
        return $this->updateField("isdelete", 1, "移动到回收站成功", '', '', 'type');
    }

    /**
     * 从回收站恢复
     */
    public function recycle()
    {
        return $this->updateField("isdelete", 0, "恢复成功", '', '', 'type');
    }

    /**
     * 默认禁用操作
     */
    public function forbid()
    {
        return $this->updateField("status", 0, "禁用成功", '', '', 'type');
    }

    /**
     * 默认恢复操作
     */
    public function resume()
    {
        return $this->updateField("status", 1, "恢复成功", '', '', 'type');
    }
    
    protected function successDelete()
    {
        $this->clearCache();
    }
    
    protected function successRecycle()
    {
        $this->clearCache();
    }
    
    protected function successForbid()
    {
        $this->clearCache();
    }
    
    protected function successResume()
    {
        $this->clearCache();
    }
    
    private function clearCache()
    {
        \Fields::clearCache();
    }
    
    /**
     * 永久删除
     */
    public function deleteForever()
    {
        $model = model('type');
        $pk = $model->getPk();
        $ids = $this->request->param($pk);
        $where[$pk] = ["in", $ids];
        if (false === $model->where($where)->delete()) {
            return ajax_return_adv_error($model->getError());
        }

        return ajax_return_adv("删除成功");
    }
}
